/*
** Copyright (C) 2010 Calin Radoni
**
** This file is part of CHScanner.
**
** CHScanner is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** CHScanner is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with CHScanner. If not, see <http://www.gnu.org/licenses/>.
*/

#include "StdAfx.h"
#include ".\workcfgmanager.h"

#include "WorkCfgDefVal.h"

#include <algorithm>

//---------------------------------------------------------------------------

WorkCfgManager::WorkCfgManager(void)
{
	display = NULL;
	applicationPath.Empty();

	localIP = 0;
	localIPMask = 0;
}

WorkCfgManager::~WorkCfgManager(void)
{
	CleanUp();
}

//---------------------------------------------------------------------------

void WorkCfgManager::CleanUp(void)
{
	WorkCfg *wc;

	for(iter=theVector.begin(); iter!=theVector.end(); iter++){
		wc = *iter;
		if(wc!=NULL){
			*iter = NULL;
			delete wc;
		}
	}
	theVector.clear();
}

//---------------------------------------------------------------------------

bool WorkCfgManager::AddConfig(WorkCfg* wcIn)
{
	WorkCfg *wce;
	int cnt;

	if(wcIn==NULL) return true;

	try{
		wce = new WorkCfg;
	}
	catch(...){
		wce = NULL;
	}
	if(wce==NULL) return false;

	if(!wce->LoadFromPointer(wcIn)){
		delete wce;
		return false;
	}

	cnt = (int)theVector.size();
	theVector.insert(theVector.begin(), wce);
	cnt = (int)theVector.size() - cnt;
	if(cnt!=1){
		delete wce;
		return false;
	}

	return true;
}

//---------------------------------------------------------------------------

bool WorkCfgManager::BuildList(void)
{
	CString searchStr;
	CString fullFileName;
	WIN32_FIND_DATA findFileData;
	HANDLE hFind;
	BOOL bRes;
	DWORD err;
	WorkCfg wce;

	searchStr = applicationPath;
	searchStr += _T("Configs\\*.chs");

	hFind = FindFirstFileEx(searchStr, FindExInfoStandard, &findFileData, FindExSearchNameMatch, NULL, 0 );
	if(hFind==INVALID_HANDLE_VALUE) return true;

	while(hFind!=INVALID_HANDLE_VALUE){
		fullFileName = applicationPath;
		fullFileName += _T("Configs\\");
		fullFileName += findFileData.cFileName;

		if(!wce.LoadFromFile(fullFileName)){
			FindClose(hFind);
			hFind = INVALID_HANDLE_VALUE;
			bRes = FALSE;

			if(display!=NULL)
				display->DisplayStatusMessageWithParamS(COULD_NOT_READ_CONFIG_FILE, findFileData.cFileName);
		}
		else{
			wce.xFileName = findFileData.cFileName;
			if(!AddConfig(&wce)){
				if(display!=NULL)
					display->DisplayStatusMessageWithParamS(COULD_NOT_LOAD_CONFIG_FILE, findFileData.cFileName);
			}

			bRes = FindNextFile(hFind, &findFileData);
			if(!bRes){
				FindClose(hFind);
				hFind = INVALID_HANDLE_VALUE;

				err = GetLastError();
				if(err==ERROR_NO_MORE_FILES) bRes = TRUE;
				else                         bRes = FALSE;
			}
		}
	}

	return bRes ? true : false;
}

//---------------------------------------------------------------------------

bool WorkCfgManagerCompareByName(WorkCfg* e1, WorkCfg* e2)
{
	int retVal;

	if(e2==NULL) return false;
	if(e1==NULL) return true;

	retVal = e1->xFileName.CompareNoCase(e2->xFileName);
	if(retVal==0){
		// unnamed ones
		retVal = e1->xDescription.CompareNoCase(e2->xDescription);
	}

	return retVal<0 ? true : false;
}

bool WorkCfgManagerCompareByDescription(WorkCfg* e1, WorkCfg* e2)
{
	int retVal;

	if(e2==NULL) return false;
	if(e1==NULL) return true;

	retVal = e1->xDescription.CompareNoCase(e2->xDescription);
	if(retVal==0)
		retVal = e1->xFileName.CompareNoCase(e2->xFileName);

	return retVal<0 ? true : false;
}

void WorkCfgManager::SortList(void)
{
	std::sort(theVector.begin(), theVector.end(), WorkCfgManagerCompareByDescription);
}

//---------------------------------------------------------------------------

void WorkCfgManager::Refresh(void)
{
	CleanUp();
	BuildList();
	SortList();
}

//---------------------------------------------------------------------------

bool WorkCfgManager::SaveConfig(WorkCfg* wcIn)
{
	CString fullFileName;

	if(wcIn==NULL) return true;

	if(wcIn->xFileName.GetLength()<1) return false;

	fullFileName = GetFullConfigFileName(wcIn->xFileName);

	return wcIn->SaveToFile(fullFileName);
}

//---------------------------------------------------------------------------

bool WorkCfgManager::DeleteConfig(WorkCfg* wcIn)
{
	CString fullFileName;
	bool err;

	if(wcIn==NULL) return true;

	if(wcIn->xFileName.GetLength()<1) return false;

	fullFileName = GetFullConfigFileName(wcIn->xFileName);

	err = false;
	try{
		CFile::Remove(fullFileName);
	}
	catch(...){
		err = true;
	}

	return !err;
}

//---------------------------------------------------------------------------

int WorkCfgManager::GetSize(void)
{
	return (int)theVector.size();
}

WorkCfg* WorkCfgManager::GetByIdx(int idxIn)
{
	if(idxIn<0)          return NULL;
	if(idxIn>=GetSize()) return NULL;

	return theVector[idxIn];
}

//---------------------------------------------------------------------------

CString WorkCfgManager::GetFullConfigFileName(CString strIn)
{
	CString fullFileName;

	fullFileName = applicationPath;
	fullFileName += _T("Configs\\");
	fullFileName += strIn;

	return fullFileName;
}

//---------------------------------------------------------------------------

void WorkCfgManager::SetLocalIPandMask(DWORD ipIn, DWORD maskIn)
{
	localIP = ipIn;
	localIPMask = maskIn;
}

bool WorkCfgManager::SaveExampleConfigurations(void)
{
	CString fullFileName;
	WorkCfgDefVal wcdv;

	if(localIP==0) return false;
	if(localIPMask==0) return false;

	wcdv.SetLocalIPandMask(localIP, localIPMask);
	wcdv.SetAs(__wcdvArpPing);
	fullFileName = GetFullConfigFileName(wcdv.xFileName);
	if(!wcdv.SaveToFile(fullFileName))
		return false;

	wcdv.SetLocalIPandMask(localIP, localIPMask);
	wcdv.SetAs(__wcdvFindWebServers);
	fullFileName = GetFullConfigFileName(wcdv.xFileName);
	if(!wcdv.SaveToFile(fullFileName))
		return false;

	wcdv.SetLocalIPandMask(localIP, localIPMask);
	wcdv.SetAs(__wcdvFindNetworkPrinters);
	fullFileName = GetFullConfigFileName(wcdv.xFileName);
	if(!wcdv.SaveToFile(fullFileName))
		return false;

	wcdv.SetLocalIPandMask(localIP, localIPMask);
	wcdv.SetAs(__wcdvWoL);
	fullFileName = GetFullConfigFileName(wcdv.xFileName);
	if(!wcdv.SaveToFile(fullFileName))
		return false;

	wcdv.SetLocalIPandMask(localIP, localIPMask);
	wcdv.SetAs(__wcdvFindDHCPServers);
	fullFileName = GetFullConfigFileName(wcdv.xFileName);
	if(!wcdv.SaveToFile(fullFileName))
		return false;
	
	wcdv.SetLocalIPandMask(localIP, localIPMask);
	wcdv.SetAs(__wcdvPromiscuousNodeScan);
	fullFileName = GetFullConfigFileName(wcdv.xFileName);
	if(!wcdv.SaveToFile(fullFileName))
		return false;
	
	wcdv.SetLocalIPandMask(localIP, localIPMask);
	wcdv.SetAs(__wcdv6PingBcast);
	fullFileName = GetFullConfigFileName(wcdv.xFileName);
	if(!wcdv.SaveToFile(fullFileName))
		return false;

	return true;
}

//---------------------------------------------------------------------------
